home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / qbasix.zip / QBASIX.PRO < prev   
Text File  |  1994-05-08  |  15KB  |  520 lines

  1. '******************************************************************************
  2. '*            QBASIX - assembler routines for QBASIC - version 2              *
  3. '*                         The QBASIX procedures                              *
  4. '*                      (c) Hans Lunsing - 04/1994                            *
  5. '******************************************************************************
  6.  
  7. 'This file holds the QBASIX procedures together with their types and
  8. 'constants. You can insert them in your own programs as needed. Don't
  9. 'forget to copy the routines called by them and the declarations going
  10. 'with them also.
  11. 'If you use procedures calling the QBASIX library QBASIX.EXE you have
  12. 'to build your program inside the shell required for using the library.
  13. 'This shell checks the existence of QBASIX and passes its position in
  14. 'memory to the program. You will find it in the file QBASIX.BAS. You can
  15. 'simply add your own program code with its declarations and procedures
  16. 'to it at the indicated positions.
  17.  
  18. DEFINT A-Z
  19.  
  20. ' Type for storing video information
  21.  
  22. TYPE VideoType
  23.   'Is necessary for use of SUB GetVideoInfo
  24.   Mode    AS INTEGER                    'video mode
  25.   Rows    AS INTEGER                    'number of rows
  26.   Cols    AS INTEGER                    'number of columns
  27.   Page    AS INTEGER                    'active screen page
  28.   Offs    AS INTEGER                    'offset of the same in video memory
  29.   Segment AS INTEGER                    'segment of the same
  30.   CRT     AS INTEGER                    'adapter: MDA = 1, CGA = 2, EGA = 3,
  31.                     'MCGA = 4, VGA = 5, HERC = 11,
  32.                     'OTHER = 0
  33.   Colour  AS INTEGER                    '-1 if color screen,
  34.                     '0 if monochrome screen
  35.   Port    AS INTEGER                    'port number of video controller
  36. END TYPE
  37.  
  38. ' Registertype to use with INTERRUPTX and MSDOS
  39.  
  40. TYPE RegTypeX
  41.   AX AS INTEGER
  42.   BX AS INTEGER
  43.   CX AS INTEGER
  44.   DX AS INTEGER
  45.   bp AS INTEGER
  46.   si AS INTEGER
  47.   di AS INTEGER
  48.   flags AS INTEGER
  49.   ds AS INTEGER
  50.   ES AS INTEGER
  51. END TYPE
  52.  
  53. ' Numbers of the assembler routines:
  54.  
  55. CONST cBlinkStatus = 0
  56. CONST cFillWindow = 1
  57. CONST cGetActiveColor = 2
  58. CONST cGetVideoInfo = 3
  59. CONST cMsDOS = 4
  60. CONST cInterruptX = 5
  61. CONST cLptReady = 6
  62. CONST cMemCopy = 7
  63. CONST cMemScan = 8
  64. CONST cSaveWindow = 9
  65. CONST cRestoreWindow = 10
  66. CONST cSetError = 11
  67. CONST cShift = 12
  68. CONST cToggleBlinkBit = 13
  69. CONST cCmd = 14
  70. CONST cSetCmd = 15
  71.  
  72. ' Logical constants:
  73.  
  74. CONST TRUE = -1, FALSE = 0
  75.  
  76. ' Numbers of the discerned video cards
  77. ' Useful with SUB GetVideoInfo
  78.  
  79. CONST OTHER = 0, MDA = 1, CGA = 2, EGA = 3, MCGA = 4, VGA = 5, HERC = 11
  80.  
  81. ' Directions
  82. ' Useful with SUB Shift
  83.  
  84. CONST LEFT = 0, RIGHT = 1
  85.  
  86. ' Effect of blink bit of screen color code
  87. ' Useful with FUNCTION BlinkStatus and SUB ToggleBlinkBit
  88.  
  89. CONST BRIGHT = 0, BLINKING = -1
  90.  
  91. ' Declarations of subroutines and functions
  92.  
  93. DECLARE FUNCTION BlinkStatus ()
  94. DECLARE FUNCTION Cmd$ ()
  95. DECLARE FUNCTION Exch (Integ)
  96. DECLARE FUNCTION GetActiveColor ()
  97. DECLARE FUNCTION GetVideoMode ()
  98. DECLARE FUNCTION Hi (i)
  99. DECLARE FUNCTION IntMax (Int1, Int2)
  100. DECLARE FUNCTION IntMin (Int1, Int2)
  101. DECLARE FUNCTION Lo (i)
  102. DECLARE FUNCTION LptReady (Lpt, Status)
  103. DECLARE FUNCTION MemScan& (Bytes&, SourceSeg, SourceOffs, Search$)
  104. DECLARE FUNCTION PeekString$ (Segment, Offset, Length)
  105. DECLARE FUNCTION PeekWord (Segment, OffSet)
  106. DECLARE FUNCTION SetWord (HiByte, LoByte)
  107. DECLARE SUB Attr (Fore, Back)
  108. DECLARE SUB FillWindow (Top, Left, Bottom, Right, Ascii, Fore, Back)
  109. DECLARE SUB GetAttr (Fore, Back)
  110. DECLARE SUB GetCursorLoc (Row, Column)
  111. DECLARE SUB GetVideoInfo (Video AS VideoType)
  112. DECLARE SUB InterruptX (IntNo, InReg AS RegTypeX, OutReg AS RegTypeX)
  113. DECLARE SUB MSDOS (InReg AS RegTypeX, OutReg AS RegTypeX)
  114. DECLARE SUB MemCopy (Bytes&, FromSeg, FromOffs, ToSeg, ToOffs)
  115. DECLARE SUB PokeWord (Segment, OffSet, Value)
  116. DECLARE SUB RestoreScreen (Buffer())
  117. DECLARE SUB SavePartScreen (Top, Left, Bottom, Right, Buffer())
  118. DECLARE SUB SaveScreen (Buffer())
  119. DECLARE SUB SetCmd (CmdStr$)
  120. DECLARE SUB SetCursorLoc (Row, Column)
  121. DECLARE SUB SetError (ErrorLevel)
  122. DECLARE SUB SetHi (i, HiByte)
  123. DECLARE SUB SetLo (i, LoByte)
  124. DECLARE SUB Shift (Direction, SomeInt, Bits)
  125. DECLARE SUB ToggleBlinkBit (Toggle)
  126.  
  127. SUB Attr (Fore, Back)
  128.   'Replacement for COLOR, especially handy when using bright background
  129.   'colors.
  130.   'Does NOT use QBASIX.EXE.
  131.  
  132.   SHARED SFore, SBack, AttrBefore
  133.   IF NOT AttrBefore THEN
  134.     SFore = 7
  135.     AttrBefore = TRUE
  136.   END IF
  137.   IF Fore >= 0 THEN SFore = Fore
  138.   IF Back >= 0 THEN SBack = Back
  139.   IF SBack AND 8 THEN
  140.     f = SFore OR 16
  141.     b = SBack XOR 8
  142.   ELSE
  143.     f = SFore
  144.     b = SBack
  145.   END IF
  146.   COLOR f, b
  147. END SUB
  148.  
  149. FUNCTION BlinkStatus
  150.   'Returns -1 if blinking text is enabled or 0 if it is not.
  151.   'Does use QBASIX.EXE.
  152.   'For indicating the effect of the blink bit it is handy to use the
  153.   'constants BRIGHT and BLINKING defined above, for instance
  154.   'IF BlinkStatus = BRIGHT THEN ....
  155.  
  156.   SHARED SegBasix, OffsBasix
  157.   DEF SEG = SegBasix
  158.   CALL ABSOLUTE(Status, cBlinkStatus, OffsBasix)
  159.   BlinkStatus = Status
  160. END FUNCTION
  161.  
  162. FUNCTION Cmd$
  163.   'Passes a command line, set by means of the switch /cmd (as with QB)
  164.   'when calling QBASIC, to the program.
  165.   'Does use QBASIX.EXE.
  166.  
  167.   SHARED SegBasix, OffsBasix
  168.   Temp$ = SPACE$(80)
  169.   DEF SEG = SegBasix
  170.   CALL ABSOLUTE(Temp$, cCmd, OffsBasix)
  171.   Cmd$ = RTRIM$(Temp$)
  172. END FUNCTION
  173.  
  174. FUNCTION Exch (Integ)
  175.   'Exchanges high and low byte of integer.
  176.   'Does NOT use QBASIX.EXE.
  177.  
  178.   Ptr1 = VARPTR(Integ)
  179.   Ptr2 = VARPTR(Exchange)
  180.   DEF SEG
  181.   POKE Ptr2, PEEK(Ptr1 + 1)
  182.   POKE Ptr2 + 1, PEEK(Ptr1)
  183.   Exch2 = Exchange
  184. END FUNCTION
  185.  
  186. SUB FillWindow (Top, Left, Bottom, Right, Ascii, Fore, Back)
  187.   'Colors foreground and/or background of a rectangular text screen
  188.   'area and/or fills it with a character.
  189.   'Does use QBASIX.EXE.
  190.  
  191.   SHARED SegBasix, OffsBasix
  192.   DEF SEG = SegBasix
  193.   CALL ABSOLUTE(Top, Left, Bottom, Right, Ascii, Fore, Back, cFillWindow, OffsBasix)
  194. END SUB
  195.  
  196. FUNCTION GetActiveColor
  197.   'Returns the screen color active in DOS.
  198.   'Does use QBASIX.EXE.
  199.  
  200.   SHARED SegBasix, OffsBasix
  201.   DEF SEG = SegBasix
  202.   CALL ABSOLUTE(ActiveColor, cGetActiveColor, OffsBasix)
  203.   GetActiveColor = ActiveColor
  204. END FUNCTION
  205.  
  206. SUB GetAttr (Fore, Back)
  207.   'Returns the colors set with the previous call of Attr.
  208.   'Meaningful only when using SUB Attr.
  209.   'Does NOT use QBASIX.EXE.
  210.  
  211.   SHARED SFore, SBack, AttrBefore
  212.   IF NOT AttrBefore THEN
  213.     SFore = 7
  214.     AttrBefore = TRUE
  215.   END IF
  216.   Fore = SFore
  217.   Back = SBack
  218. END SUB
  219.  
  220. SUB GetCursorLoc (Row, Column)
  221.   'Gets the location of the cursor by way of the BIOS.
  222.   'Does use SUB InterruptX and QBASIX.EXE.
  223.  
  224.   DIM Reg AS RegTypeX
  225.   Reg.AX = &H300
  226.   Reg.BX = 0
  227.   InterruptX &H10, Reg, Reg
  228.   Row = Reg.DX \ 256 + 1                'from 0 to 1 as a base
  229.   Column = Reg.DX MOD 256 + 1
  230. END SUB
  231.  
  232. SUB GetVideoInfo (Video AS VideoType)
  233.   'Returns information about the video configuration.
  234.   'Does use TYPE VideoType and QBASIX.EXE.
  235.   'It is handy to test for the type of video card with the help of the
  236.   'constants VGA, EGA etc., defined above.
  237.  
  238.   SHARED SegBasix, OffsBasix
  239.   DEF SEG = SegBasix
  240.   CALL ABSOLUTE(Video, cGetVideoInfo, OffsBasix)
  241. END SUB
  242.  
  243. FUNCTION GetVideoMode
  244.   'Returns the active video mode.
  245.   'Does use SUB InterruptX and QBASIX.EXE.
  246.  
  247.   DIM Reg AS RegTypeX
  248.   Reg.AX = &HF00
  249.   InterruptX &H10, Reg, Reg
  250.   GetVideoMode = (Reg.AX AND &HFF)
  251. END FUNCTION
  252.  
  253. FUNCTION Hi(Integ)
  254.   'Returns high byte of integer.
  255.   'Does NOT use QBASIX.EXE.
  256.  
  257.   DEF SEG
  258.   Hi = PEEK(VARPTR(Integ) + 1)
  259. END FUNCTION
  260.  
  261. SUB InterruptX (IntNo, InReg AS RegTypeX, OutReg AS RegTypeX)
  262.   'Executes interrupt.
  263.   'Does use TYPE RegTypeX and QBASIX.EXE.
  264.  
  265.   SHARED SegBasix, OffsBasix
  266.   DEF SEG = SegBasix
  267.   CALL ABSOLUTE(IntNo, InReg, OutReg, cInterruptX, OffsBasix)
  268. END SUB
  269.  
  270. FUNCTION IntMax(Int1, Int2)
  271.   'Returns the maximum of 2 integers
  272.   'Does NOT use QBASIX.EXE.
  273.  
  274.   IF Int1 >= Int2 THEN
  275.     IntMax = Int1
  276.   ELSE
  277.     IntMax = Int2
  278.   END IF
  279. END FUNCTION
  280.  
  281. FUNCTION IntMin(Int1, Int2)
  282.   'Returns the minimum of 2 integers
  283.   'Does NOT use QBASIX.EXE.
  284.  
  285.   IF Int1 <= Int2 THEN
  286.     IntMin = Int1
  287.   ELSE
  288.     IntMin = Int2
  289.   END IF
  290. END FUNCTION
  291.  
  292. FUNCTION Lo(Integ)
  293.   'Returns low byte of integer.
  294.   'Does NOT use QBASIX.EXE.
  295.  
  296.   Lo = Integ AND 255
  297. END FUNCTION
  298.  
  299. FUNCTION LptReady (Lpt, Status)
  300.   'Determines if printer is ready and passes printer status.
  301.   'Does use QBASIX.EXE.
  302.  
  303.   SHARED SegBasix, OffsBasix
  304.   DEF SEG = SegBasix
  305.   CALL ABSOLUTE(Lpt, Status, Ready, cLptReady, OffsBasix)
  306.   LptReady = Ready
  307. END FUNCTION
  308.  
  309. SUB MemCopy (Bytes&, FromSeg, FromOffs, ToSeg, ToOffs)
  310.   'Copies a number of bytes from one memory location to another.
  311.   'Does use QBASIX.EXE.
  312.  
  313.   SHARED SegBasix, OffsBasix
  314.   DEF SEG = SegBasix
  315.   CALL ABSOLUTE(Bytes&, FromSeg, FromOffs, ToSeg, ToOffs, cMemCopy, OffsBasix)
  316. END SUB
  317.  
  318. FUNCTION MemScan& (Bytes&, SourceSeg, SourceOffs, Search$)
  319.   'Scans a memory block of at most 64Kb for a string.
  320.   'Does use QBASIX.EXE.
  321.  
  322.   SHARED SegBasix, OffsBasix
  323.   DEF SEG = SegBasix
  324.   CALL ABSOLUTE(Bytes&, SourceSeg, SourceOffs, Search$, Where&, cMemScan, OffsBasix)
  325.   MemScan& = Where&
  326. END FUNCTION
  327.  
  328. SUB MSDOS (InReg AS RegTypeX, OutReg AS RegTypeX)
  329.   'Executes DOS interrupt.
  330.   'Does use TYPE RegTypeX and QBASIX.EXE.
  331.  
  332.   SHARED SegBasix, OffsBasix
  333.   DEF SEG = SegBasix
  334.   CALL ABSOLUTE(InReg, OutReg, cMsDOS, OffsBasix)
  335. END SUB
  336.  
  337. FUNCTION PeekString$ (Segment, Offset, Length)
  338.   'Reads a string of specified length from specified address.
  339.   'Does NOT use QBASIX.EXE.
  340.  
  341.   IF Length > 0 THEN
  342.     PeekString$ = SPACE$(Length)
  343.     DEF SEG = Segment
  344.     FOR i = 1 TO Length
  345.       MID$(PeekString$, i, 1) = CHR$(PEEK(Offset - 1 + i))
  346.     NEXT i
  347.   ELSE
  348.     PeekString$ = ""
  349.   END IF
  350. END FUNCTION
  351.  
  352. FUNCTION PeekWord (Segment, Offset)
  353.   'Reads a word from the specified address.
  354.   'Does NOT use QBASIX.EXE.
  355.  
  356.   DEF SEG = Segment
  357.   Word = PEEK(Offset)
  358.   HiByte = PEEK(Offset + 1)
  359.   DEF SEG
  360.   POKE VARPTR(Word) + 1, HiByte
  361.   PeekWord = Word
  362. END FUNCTION
  363.  
  364. SUB PokeWord (Segment, Offset, Word)
  365.   'Writes a word to the specified address.
  366.   'Does NOT use QBASIX.EXE.
  367.  
  368.   DEF SEG
  369.   HiByte = PEEK(VARPTR(Word) + 1)
  370.   DEF SEG = Segment
  371.   POKE Offset, Word
  372.   POKE Offset + 1, HiByte
  373. END SUB
  374.  
  375. SUB RestoreScreen (Buffer())
  376.   'Restores rectangular text screen area (window) from buffer array.
  377.   'Meaningful only when using SUB SaveScreen or SUB SavePartScreen.
  378.   'Does use SUB Attr and QBASIX.EXE.
  379.  
  380.   SHARED SegBasix, OffsBasix
  381.   i = LBOUND(Buffer)
  382.   IF UBOUND(Buffer) - i < 8 THEN EXIT SUB
  383.   DEF SEG = SegBasix
  384.   CALL ABSOLUTE(Buffer(i + 4), Buffer(i + 5), Buffer(i + 6), Buffer(i + 7), SEG Buffer(i + 8), cRestoreWindow, OffsBasix)
  385.   DEF SEG
  386.   LOCATE Buffer(i), Buffer(i + 1)
  387.   Attr Buffer(i + 2), Buffer(i + 3)
  388. END SUB
  389.  
  390. SUB SavePartScreen (Top, Left, Bottom, Right, Buffer())
  391.   'Saves screen window with cursor location and color setting in buffer
  392.   'array. Meaningful only when using SUB RestoreScreen.
  393.   'Does use SUB GetAttr and QBASIX.EXE.
  394.  
  395.   SHARED SegBasix, OffsBasix
  396.   'N.B.: valid coordinates are not checked upon.
  397.   i = LBOUND(Buffer)
  398.   j = i + 7 + (Bottom - Top + 1) * (Right - Left + 1)
  399.   IF UBOUND(Buffer) < j THEN
  400.     REDIM Buffer(i TO j)
  401.   END IF
  402.   Buffer(i) = CSRLIN
  403.   Buffer(i + 1) = POS(0)
  404.   GetAttr Buffer(i + 2), Buffer(i + 3)
  405.   Buffer(i + 4) = Top
  406.   Buffer(i + 5) = Left
  407.   Buffer(i + 6) = Bottom
  408.   Buffer(i + 7) = Right
  409.   DEF SEG = SegBasix
  410.   CALL ABSOLUTE(Top, Left, Bottom, Right, SEG Buffer(i + 8), cSaveWindow, OffsBasix)
  411. END SUB
  412.  
  413. SUB SaveScreen (Buffer())
  414.   'Saves full screen with cursor location and color setting in buffer
  415.   'array, taking into account the active video mode.
  416.   'Meaningful only when using SUB RestoreScreen.
  417.   'Does use SUB GetAttr, SUB GetVideoInfo and QBASIX.EXE.
  418.  
  419.   SHARED SegBasix, OffsBasix
  420.   DIM Video AS VideoType
  421.   GetVideoInfo Video
  422.   i = LBOUND(Buffer)
  423.   j = i + 7 + Video.Rows * Video.Cols
  424.   IF UBOUND(Buffer) < j THEN
  425.     REDIM Buffer(i TO j)
  426.   END IF
  427.   Buffer(i) = CSRLIN
  428.   Buffer(i + 1) = POS(0)
  429.   GetAttr Buffer(i + 2), Buffer(i + 3)
  430.   Buffer(i + 4) = 1
  431.   Buffer(i + 5) = 1
  432.   Buffer(i + 6) = Video.Rows
  433.   Buffer(i + 7) = Video.Cols
  434.   DEF SEG = SegBasix
  435.   CALL ABSOLUTE(1, 1, Video.Rows, Video.Cols, SEG Buffer(i + 8), cSaveWindow, OffsBasix)
  436. END SUB
  437.  
  438. SUB SetCmd (CmdStr$)
  439.   'Changes the command line meant for the basic program from inside QBASIC.
  440.   'Does use QBASIX.EXE.
  441.  
  442.   SHARED SegBasix, OffsBasix
  443.   IF IsQBASIX THEN
  444.     DEF SEG = SegBasix
  445.     CALL ABSOLUTE(CmdStr$, cSetCmd, OffsBasix)
  446.   ELSE
  447.     PRINT "Geen opdrachtregel beschikbaar omdat QBASIX niet is geladen."
  448.   END IF
  449. END SUB
  450.  
  451. SUB SetCursorLoc (Row, Column)
  452.   'Sets cursor location by way of the BIOS
  453.   'Does use SUB InterruptX and QBASIX.EXE.
  454.  
  455.   DIM Reg AS RegTypeX
  456.   Reg.AX = &H200
  457.   Reg.BX = 0
  458.   Reg.DX = (Row - 1) * 256 + (Column - 1) 'from 1 to 0 as a base
  459.   InterruptX &H10, Reg, Reg
  460. END SUB
  461.  
  462. SUB SetError (ErrorLevel)
  463.   'Sets termination code (error level) of the program.
  464.   'Does use QBASIX.EXE.
  465.  
  466.   SHARED SegBasix, OffsBasix
  467.   DEF SEG = SegBasix
  468.   CALL ABSOLUTE(ErrorLevel, cSetError, OffsBasix)
  469. END SUB
  470.  
  471. SUB SetHi (i, HiByte)
  472.   'Gives high byte of integer another value.
  473.   'Does NOT use QBASIX.EXE.
  474.  
  475.   DEF SEG
  476.   POKE VARPTR(i) + 1, HiByte
  477. END SUB
  478.  
  479. SUB SetLo (i, LoByte)
  480.   'Gives low byte of integer another value.
  481.   'Does NOT use QBASIX.EXE.
  482.  
  483.   DEF SEG
  484.   POKE VARPTR(i), LoByte
  485. END SUB
  486.  
  487. FUNCTION SetWord (HiByte, LoByte)
  488.   'Forms integer from high byte and low byte.
  489.   'Does NOT use QBASIX.EXE.
  490.  
  491.   DEF SEG
  492.   POKE VARPTR(i) + 1, HiByte
  493.   POKE VARPTR(i), LoByte
  494.   SetWord = i
  495. END FUNCTION
  496.  
  497. SUB Shift (Direction, SomeInt, Bits)
  498.   'Shifts bits of integer a number of places to the left or the right.
  499.   'Does use QBASIX.EXE.
  500.   'For indicating the direction in which the bits are to be shifted it
  501.   'is convenient to use the constants LEFT and RIGHT defined above.
  502.  
  503.   SHARED SegBasix, OffsBasix
  504.   DEF SEG = SegBasix
  505.   CALL ABSOLUTE(Direction, SomeInt, Bits, cShift, OffsBasix)
  506. END SUB
  507.  
  508. SUB ToggleBlinkBit (Toggle)
  509.   'Sets the effect of the blink bit of the screen color code to blinking
  510.   'text or bright background.
  511.   'Does use QBASIX.EXE.
  512.   'For indicating the effect of the blink bit it is handy to use the
  513.   'constants BRIGHT and BLINKING defined above, for instance
  514.   'CALL ToggleBlinkbit (BRIGHT)
  515.  
  516.   SHARED SegBasix, OffsBasix
  517.   DEF SEG = SegBasix
  518.   CALL ABSOLUTE(Toggle, cToggleBlinkBit, OffsBasix)
  519. END SUB
  520.